using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using LitJson;
using Spine;
using Spine.Unity;
using Spine.Unity.AttachmentTools;
using UnityEngine;

//spine 局部变装
public class SpineCloth : MonoBehaviour
{

    public SkeletonGraphic skeletonGraphic;
    [SerializeField]
    List<SkinComponentConfig> componentList = new List<SkinComponentConfig>();
    Dictionary<string, string> currentSkin = new Dictionary<string, string>();
    private async void Start()
    {
        foreach (var item in componentList)
        {
            currentSkin.Add(item.component, item.defaultSkin);
        }
        skeletonGraphic = GetComponent<SkeletonGraphic>();
        RefreshSkin();
    }
    int index = 0,index2 = 0;
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            index++;
            index = index % componentList.Count;
            if (componentList[0].skins.Count > index)
            {
                ChangeCompoennt(componentList[0].component, componentList[0].skins[index]);
            }

        }
        if (Input.GetKeyDown(KeyCode.D))
        {
            index2++;
            index2 = index2 % componentList.Count;

            if (componentList[1].skins.Count > index2)
            {
                ChangeCompoennt(componentList[1].component, componentList[1].skins[index2]);
            }

        }


        if (Input.GetKeyDown(KeyCode.T))
        {
            string slotName = "face_cat";
            string skinName = "face/china";
            var skeletonData = skeletonGraphic.SkeletonData;
            Skin skin = skeletonData.FindSkin(skinName);
            int slotIndex = skeletonData.FindSlotIndex(slotName);
            ChangeAttachment(skeletonGraphic.Skeleton, slotName, GetAttachmentFromSkin(skin, slotIndex, slotName));
        }
    }
    public void ChangeCompoennt(string component, string targetSkin){
        int index= componentList.FindIndex(x=>x.component==component);
        if (index!=-1)
        {
            if (componentList[index].skins.Contains(targetSkin)||string.IsNullOrEmpty(targetSkin))
            {
                currentSkin[component] = targetSkin;
                RefreshSkin();
            }
            else{
                Debug.LogError("不存在的皮肤");
            }
        }
    }
    public string GetComponentSkin(string component)
    {
        int index = componentList.FindIndex(x => x.component == component);
        if (index != -1)
        {
            return currentSkin[component];
        }
        return "";
    }

    /// <summary>
    /// 刷新Spine骨骼的皮肤，实现局部换肤功能。根据当前存储的皮肤配置，创建一个新的皮肤并应用到骨骼上，然后更新骨骼的姿势和动画状态。
    /// </summary>
    void RefreshSkin()
    {
        // 创建一个名为 "NewSkin" 的新皮肤实例
        Skin newSkin = new Skin("NewSkin");
        // 遍历当前存储的皮肤配置字典
        foreach (var item in currentSkin)
        {
            // 检查当前皮肤名称是否不为空
            if (!string.IsNullOrEmpty(item.Value))
            {
                // 从骨骼数据中查找指定名称的皮肤，并将其添加到新皮肤中
                newSkin.AddSkin(skeletonGraphic.SkeletonData.FindSkin(item.Value));
            }
        }
        // 将新创建的皮肤应用到骨骼上
        skeletonGraphic.Skeleton.SetSkin(newSkin);

        // 将骨骼的插槽设置为初始姿势
        skeletonGraphic.Skeleton.SetSlotsToSetupPose();
        // 获取骨骼的动画状态
        Spine.AnimationState state = skeletonGraphic.AnimationState;
        // 将动画状态应用到骨骼上
        state.Apply(skeletonGraphic.Skeleton);
    }

    public Attachment GetAttachmentFromSkin(Skin skin, int slotIndex, string slotName)
    {
        return skin.GetAttachment(slotIndex, slotName);
    }
    public void ChangeAttachment(Skeleton skeleton ,string targetSlotName, Attachment attachment)
    {
        if (attachment == null)
        {
            Debug.LogWarning("GetAttachmentFromSkin() return , attachment == null");
        }
        //  遍历targetSkeleton所有slot，创建新皮肤
        Skin newSkin = new Skin("NewSkin");
        foreach (var item in skeleton.Slots)
        {
            string slotName = item.ToString();
            int slotIndex = item.Skeleton.FindSlotIndex(slotName);
            Attachment tempAttackment = null;
            if (slotName.Equals(targetSlotName))
            {
                tempAttackment = attachment;
                Debug.LogWarning("Replace slotIndex: " + slotIndex + ", slotName: " + slotName);
            }
            else
            {
                tempAttackment = item.Attachment;
            }
            Skin.SkinEntry entry = new Skin.SkinEntry(slotIndex, slotName, tempAttackment);
            newSkin.Attachments.Add(entry, tempAttackment);
            Debug.Log("slotIndex: " + slotIndex + ", slotName: " + slotName);
        }
        skeleton.SetSkin(newSkin);
    }
}
